/*
 *  Copyright 2010 "Johan Maasing" <johan@zoom.nu>.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package nu.zoom.ui.gaderian;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;

import javax.swing.ImageIcon;

import nu.zoom.ui.Resources;

/**
 * An implementation of resources that scan the class path for all instances of
 * the file "META-INF/org/ops4j/gaderian/module.properties" and collates all
 * properties from all the files found.
 * 
 * @author "Johan Maasing" &lt;johan@zoom.nu&gt;
 */
public class ResourcesImpl implements Resources {
	ArrayList<Properties> props = null;

	public ResourcesImpl() {
	}

	@Override
	public synchronized String getMessage(final String key)
			throws ResourceNotFoundException {
		try {
			if (!containsMessage(key)) {
				throw new ResourceNotFoundException(
						"Unable to find a string for key: " + key);
			}
		} catch (IOException e) {
			throw new ResourceNotFoundException(e);
		}
		for (Properties properties : props) {
			Object object = properties.get(key);
			if (object != null) {
				return (String) object;
			}
		}
		return null;
	}

	@Override
	public synchronized String format(final String key, final Object... args)
			throws ResourceNotFoundException {
		try {
			if (!containsMessage(key)) {
				throw new ResourceNotFoundException(
						"Unable to find a string for key: " + key);
			}
		} catch (IOException e) {
			throw new ResourceNotFoundException(e);
		}
		final String template = getMessage(key);
		return String.format(template, args);
	}

	private synchronized boolean containsMessage(final String key)
			throws IOException {
		if (props == null) {
			findResources();
		}
		for (Properties properties : props) {
			Object object = properties.get(key);
			if (object != null) {
				return true;
			}
		}
		return false;
	}

	@Override
	public synchronized ImageIcon getIcon(final String key)
			throws ResourceNotFoundException {
		String resourceName = getMessage(key);
		URL url = getClass().getResource(resourceName);
		ImageIcon icon = null;
		if (url != null) {
			icon = new ImageIcon(url);
			if (icon != null) {
				return icon;
			}
		}
		throw new ResourceNotFoundException("Unable to load Icon resource: "
				+ key);
	}

	private synchronized void findResources() throws IOException {
		props = new ArrayList<Properties>();
		ClassLoader contextClassLoader = Thread.currentThread()
				.getContextClassLoader();
		Enumeration<URL> resources = contextClassLoader
				.getResources("META-INF/org/ops4j/gaderian/module.properties");
		while (resources.hasMoreElements()) {
			URL resourceURL = resources.nextElement();
			Properties p = new Properties();
			p.load(resourceURL.openStream());
			props.add(p);
		}
	}
}
